package com.zf.study.handler;

import com.zf.study.entity.ClientInfo;
import com.zf.study.message.MessageParser;
import com.zf.study.message.MessageType;
import java.io.*;
import java.net.Socket;
import java.net.SocketException;
import java.util.Map;
import java.util.concurrent.CopyOnWriteArrayList;

public class ChatHandler implements Runnable {

    private String tag;
    private Socket socket;

    private Map<String,PrintWriter> userWriterMap;

    private Map<String,String> userMap;

    public ChatHandler(String tag, Socket socket, Map<String,PrintWriter> userWriterMap, Map<String,String> userMap) {
        this.tag = tag;
        this.socket = socket;
        this.userWriterMap = userWriterMap;
        this.userMap = userMap;
    }

    @Override
    public void run() {
        BufferedReader reader = null;
        PrintWriter writer = null;
        ClientInfo clientInfo = null;
        try {
            reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            //自动刷新
            writer = new PrintWriter(new OutputStreamWriter(socket.getOutputStream()), true);

            // 用户名输入循环，直到输入有效的用户名
            String username = null;
            while (username == null) {
                writer.println("请输入您的用户名:");
                String inputUsername = reader.readLine();
                
                if (inputUsername == null || inputUsername.trim().isEmpty()) {
                    writer.println("用户名不能为空，请重新输入。");
                    continue;
                }
                inputUsername = inputUsername.trim();
                // 检查用户名是否已存在
                if (userMap.containsKey(inputUsername)) {
                    writer.println("用户名 '" + inputUsername + "' 已存在，请选择其他用户名。");
                    continue;
                }
                
                // 用户名有效，设置并跳出循环
                username = inputUsername;
                userMap.put(username, tag);
            }
            userWriterMap.put(username, writer);
            // 添加客户端到心跳检测列表
            clientInfo = new ClientInfo(tag, writer, socket);
            // 设置用户名
            clientInfo.setUsername(username);
            HeartBeatHandler.addClient(clientInfo);
            
            writer.println("欢迎 " + username + " 加入聊天室!");
            
            String msg = null;
            while ((msg = reader.readLine()) != null) {
                MessageType type = MessageParser.parseMessageType(msg);
                if(type.equals(MessageType.HEARTBEAT)){
                    this.handleHeartbeat(tag);
                }else if(type.equals(MessageType.CHAT)){
                    this.handleChat(msg,username);
                    //广播消息给其他客户端
                    this.broadcast(userWriterMap,writer,msg, username);
                }else if(type.equals(MessageType.HELP)){
                    this.handleHelp(writer);
                }else if(type.equals(MessageType.LIST_USERS)){
                    this.handleListUsers(writer);
                }else if(type.equals(MessageType.PRIVATE_CHAT)){
                    this.handlePrivateChat(msg, writer);
                }else if(type.equals(MessageType.QUIT)){
                    this.handleQuit(writer);
                    break; // 退出循环，结束线程
                }else if(type.equals(MessageType.UNKNOWN)){
                    this.handleUnknown(writer, msg);
                }
            }
        } catch (SocketException e) {
            System.out.println("客户端" + this.tag + "连接出现问题，可能是已断开");
        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {
            try {
                // 从userMap中移除用户名
                if (clientInfo != null && clientInfo.getUsername() != null) {
                    userMap.remove(clientInfo.getUsername());
                    userWriterMap.remove(clientInfo.getUsername());
                }
                // 确保从心跳检测列表中移除客户端
                if (clientInfo != null) {
                    HeartBeatHandler.removeClient(clientInfo);
                }
                if (reader != null) reader.close();
                if (writer != null) writer.close();
                if (socket != null && !socket.isClosed()) {
                    socket.close();
                }
            } catch (IOException e) {
                System.err.println("关闭资源时出错：" + e.getMessage());
            }
        }
    }

    private void handleUnknown(PrintWriter writer, String msg) {
        writer.println("未知命令: " + msg);
    }

    private void handleQuit(PrintWriter writer) {
        writer.println("再见，客户端！服务端正在断开连接。");
    }

    private void handlePrivateChat(String msg, PrintWriter writer) {
        String username = extractUsernameFromPrivateMessage(msg);
        if(userWriterMap.containsKey(username)){
            userWriterMap.get(username).println("私聊[" + tag + "]说: " + extractMessageContent(msg));
        }else{
            writer.println("用户[" + username + "]不存在");
        }
    }

    private void handleListUsers(PrintWriter writer) {
        CopyOnWriteArrayList<ClientInfo> clientList = HeartBeatHandler.clientList;
        writer.println("当前系统在线的用户共有"+clientList.size()+"位，分别为");
        for (ClientInfo clientInfo : clientList) {
           writer.println(clientInfo.getUsername() + "(" + clientInfo.getTag() + ")");
        }
    }

    private void handleHelp(PrintWriter writer) {
        writer.println("支持的命令:");
        writer.println("/help - 显示帮助信息");
        writer.println("/users - 显示在线用户");
        writer.println("/quit - 退出聊天室");
        writer.println("@用户名 内容的信息格式 - 发送私聊消息 例如：@张三 你好 对张三私聊信息为你好");
        writer.println("直接输入 - 发送聊天消息");
    }

    public void broadcast(Map<String,PrintWriter> userWriterMap,PrintWriter writer,String  msg, String username){
        for (PrintWriter printWriter : userWriterMap.values()) {
            if(printWriter != writer){
                printWriter.println(username + " 说: " + msg);
            }
        }
    }


    public void handleHeartbeat(String tag) {
        HeartBeatHandler.updateLastResponseTime(this.tag);
    }

    public void handleChat(String msg,String username){
        System.out.println("服务端收到消息 --- 来自客户端: " + username + " | Tag: " + this.tag + " | 内容: " + msg);
    }

    /**
     * 从私聊消息中提取用户名
     * @param msg 格式为"@用户名 消息内容"的字符串
     * @return 提取的用户名，如果没有找到则返回null
     */
    public String extractUsernameFromPrivateMessage(String msg) {
        if (msg == null || !msg.startsWith("@")) {
            return null;
        }

        // 查找@符号后第一个空格的位置
        int firstSpaceIndex = msg.indexOf(' ', 1);
        if (firstSpaceIndex != -1) {
            // 返回@和第一个空格之间的内容作为用户名
            return msg.substring(1, firstSpaceIndex);
        } else {
            // 如果没有空格，整个内容都是用户名
            return msg.substring(1);
        }
    }

    /**
     * 从私聊消息中提取实际消息内容
     * @param msg 格式为"@用户名 消息内容"的字符串
     * @return 提取的消息内容
     */
    public String extractMessageContent(String msg) {
        if (msg == null || !msg.startsWith("@")) {
            return msg;
        }
        // 查找@符号后第一个空格的位置
        int firstSpaceIndex = msg.indexOf(' ', 1);
        if (firstSpaceIndex != -1) {
            // 返回第一个空格后的内容作为消息
            return msg.substring(firstSpaceIndex + 1);
        } else {
            // 如果没有空格，说明只有用户名没有消息内容
            return "";
        }
    }

}